package com.iteaj.iot.test.server.fixed;

import com.iteaj.iot.FrameworkManager;
import com.iteaj.iot.ProtocolException;
import com.iteaj.iot.consts.ExecStatus;
import com.iteaj.iot.redis.handle.RedisListHandle;
import com.iteaj.iot.server.ServerProtocolHandle;
import com.iteaj.iot.server.TcpServerComponent;
import com.iteaj.iot.test.ClientSnGen;
import com.iteaj.iot.test.IotTestHandle;
import com.iteaj.iot.test.TestConst;
import com.iteaj.iot.test.taos.TaosBreakerUsingStable;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 固定长度+redis测试
 */
public class FixedLengthClientRequestHandle implements ServerProtocolHandle<FixedLengthClientRequestProtocol>
        , RedisListHandle<FixedLengthClientRequestProtocol, TaosBreakerUsingStable>, IotTestHandle {

    private String equipCode;
    @Autowired
    private ScheduledExecutorService scheduler;
    private Logger logger = LoggerFactory.getLogger(getClass());

    // 从redis消费数据
    @Override
    public Integer consumer(List<TaosBreakerUsingStable> objects) {
        return objects.size();
    }

    // 此方法直接写业务
    @Override
    public Object handle(FixedLengthClientRequestProtocol protocol) {
        final String equipCode = this.equipCode = protocol.getEquipCode();

        new Thread(() -> {
            final long id = Thread.currentThread().getId();
            new FixedLengthServerRequestProtocol(equipCode).sync(2000).request(protocol1 -> {
                final long id1 = Thread.currentThread().getId();
                if (protocol1 instanceof FixedLengthServerRequestProtocol) {
                    final ExecStatus execStatus = ((FixedLengthServerRequestProtocol) protocol1).getExecStatus();
                    // 同步请求 调用线程 == 执行线程
                    if (execStatus == ExecStatus.timeout) {
                        if (id == id1) {
                            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端同步超时测试", "sync(long) + request()", equipCode, "通过");
                        } else {
                            logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端同步超时测试", "sync(long) + request()", equipCode, "失败");
                        }
                    } else {
                        if (id == id1) {
                            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端同步测试", "sync(long) + request()", equipCode, "通过");
                        } else {
                            logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端同步测试", "sync(long) + request()", equipCode, "失败");
                        }
                    }
                }

                return null;
            });

            new FixedLengthServerRequestProtocol(equipCode).timeout(2000).request(protocol2 -> {
                final long id1 = Thread.currentThread().getId();
                if (protocol2 instanceof FixedLengthServerRequestProtocol) {
                    final ExecStatus execStatus = ((FixedLengthServerRequestProtocol) protocol2).getExecStatus();
                    if (execStatus == ExecStatus.timeout) {
                        // 异步请求 调用线程 != 执行线程
                        if (id != id1) {
                            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端异步超时测试", "timeout(long) + request()", equipCode, "通过");
                        } else {
                            logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端异步超时测试", "timeout(long) + request()", equipCode, "失败");
                        }
                    } else {
                        if (id != id1) {
                            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端异步测试", "timeout(long) + request()", equipCode, "通过");
                        } else {
                            logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "服务端异步测试", "timeout(long) + request()", equipCode, "失败");
                        }
                    }
                }

                return null;
            });
        }).start();

        return null;
    }

    /**
     * 数据将写入到此Key的list里面
     * @return
     */
    @Override
    public String getKey() {
        return "Fixed_Redis_Key";
    }

    @Override
    public void start() throws Exception {
        String equipCode = ClientSnGen.getMessageId();

        TcpServerComponent serverComponent = FrameworkManager.getServerComponent(FixedLengthServerMessage.class);
        Channel channel = serverComponent.getDeviceManager().find(this.equipCode);
        if(channel.isActive()) {
            channel.deregister();
            new FixedLengthServerRequestProtocol(this.equipCode).sync(2000).request(protocol -> {
                if(protocol.getExecStatus() != ExecStatus.success) {
                    logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "设备解除注册同步测试", "sync(long) + request()", equipCode, "通过("+protocol.getExecStatus()+")");
                } else {
                    logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "设备解除注册同步测试", "sync(long) + request()", equipCode, "失败");
                }
            });

            new FixedLengthServerRequestProtocol(this.equipCode).timeout(2000).request(protocol -> {
                if(protocol.getExecStatus() != ExecStatus.success) {
                    logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "设备解除注册异步测试", "request()", equipCode, "通过(" + protocol.getExecStatus() + ")");
                } else {
                    logger.error(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "设备解除注册异步测试", "request()", equipCode, "失败");
                }
            });

            // 关闭此链接
            channel.close();
        }
        try {
            new FixedLengthServerRequestProtocol(equipCode).request();
        } catch (ProtocolException e) {
            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "无设备异步测试", "request()", equipCode, "通过("+e.getMessage()+")");
        }

        try {
            new FixedLengthServerRequestProtocol(equipCode).sync(1000).request();
        } catch (ProtocolException e) {
            logger.info(TestConst.LOGGER_PROTOCOL_FUNC_DESC, "无设备同步测试", "sync(long) + request()", equipCode, "通过("+e.getMessage()+")");
        }

        TimeUnit.SECONDS.sleep(2);
    }

    @Override
    public int getOrder() {
        return 1000 * 50;
    }
}
